package com.javaspeak.designpatterns.go4.behavioural.observer;

import java.util.ArrayList;
import java.util.List;

/**
 * This example uses the Observer pattern.
 * <p>
 * In the Observer pattern there is one Observable and there are many Observers.
 * <p>
 * The idea is that when something specific happens with the Observable all
 * subscribed Observers are notified of this happening.
 * <p>
 * In this example we have a Observable called ObservableImpl which adds three
 * different Observers to its list of Observers using its addObserver(..)
 * method.  Each of the Observers implements Observer.
 * <p>
 * ObservableImpl then calls notifyObservers(ObservableEvent e) to inform all
 * observers of a new happening.  The happening is encapsulated in a
 * ObservableEventImpl which holds a messages. The message is "Hello Everyone!".
 * <p>
 * Internally the notifyObservers(..) method loops through all its subscribed
 * Observers and calls the receiveObservableEvent(ObservableEvent e ) on each
 * of them.
 * <p>
 * Each Observer then retrieves the message from then ObservableEvent and prints
 * it to the console.
 *
 * @author John Dickerson
 */
public class ApplicationObserver implements Observable {

    List<Observer> observers = new ArrayList<Observer>();

    /* (non-Javadoc)
     * @see com.javaspeak.designpatterns.go4.behavioural.observer.
     *      Observable#addObserver(com.javaspeak.designpatterns.go4.
     *          behavioural.observer.Observer)
     */
    @Override
    public void addObserver(Observer observer) {

        observers.add( observer );
    }

    /* (non-Javadoc)
     * @see com.javaspeak.designpatterns.go4.behavioural.observer.
     *      Observable#notifyObservers(com.javaspeak.designpatterns.go4.
     *          behavioural.observer.ObservableEvent)
     */
    @Override
    public void notifyObservers(ObservableEvent observableEvent) {

        for ( Observer observer : observers ){

            observer.receiveObservableEvent( observableEvent );
        }
    }

    /**
     * Runs the example
     */
    public void runExample(){

        // This class is the Observable

        // First we create some Observers
        Observer observerOne = new ObserverImpl( "ObserverOne" );
        Observer observerTwo = new ObserverImpl( "ObserverTwo" );
        Observer observerThree = new ObserverImpl( "ObserverTwo" );

        // Next we subscribe those observers so that they are observing the
        // Observable. "Observing" in this example means they are waiting for
        // ObservavleEvents. In other words the Observers are waiting for their
        // receiveObservableEvent(..) method to be called.
        addObserver( observerOne );
        addObserver( observerTwo );
        addObserver( observerThree );

        // The Observable (this class) loops through its sunscribed observers
        // and calls receiveObservableEvent(..) on each of them. A
        // ObservableEvent is passed to each of the Observers which has the
        // message, "Hello Everyone!" in it.  The Observers in turn print the
        // message to the console.
        notifyObservers( new ObservableEventImpl( "Hello Everyone!" ) );
    }


    /**
     * @param args
     */
    public static void main(String[] args) {

        ApplicationObserver application = new ApplicationObserver();
        application.runExample();
    }

}
